#include "uarttouart.h"
#include "sdk_project_config.h"
#include <stdio.h>
#include <string.h>

#define UART5_INSTANCE INST_UART_5
#define UART2_INSTANCE INST_UART_2
#define BUFFER_SIZE 256U
#define TIMEOUT 500U

static uint8_t g_buffer[BUFFER_SIZE];
static uint8_t g_bufferldx = 0;

// UART5接收回调
void UART5_RxCallback(void *driverState, uart_event_t event, void *userData)
{
    (void)driverState;
    (void)userData;
    if (event == UART_EVENT_RX_FULL) {
        if ((g_buffer[g_bufferldx] != '\n') && (g_buffer[g_bufferldx] != '\r') && (g_bufferldx != (BUFFER_SIZE - 2U))) {
            g_bufferldx++;
            UART_DRV_SetRxBuffer(UART5_INSTANCE, &g_buffer[g_bufferldx], 1U);
        } else {
            g_buffer[g_bufferldx++] = '\r';
            g_buffer[g_bufferldx++] = '\n';
            g_buffer[g_bufferldx]   = '\0';
        }
    }
}

// UART5接收数据并用UART2打印输出
void UART5_ReceiveAndPrintToUART2(void)
{
    status_t status;
    uint32_t bytesRemaining;
    g_bufferldx = 0;
    UART_DRV_InstallRxCallback(UART5_INSTANCE, UART5_RxCallback, NULL);
    while (1) {
        UART_DRV_ReceiveData(UART5_INSTANCE, g_buffer, 1U);
        while (UART_DRV_GetReceiveStatus(UART5_INSTANCE, &bytesRemaining) == STATUS_BUSY)
            ;
        status = UART_DRV_GetReceiveStatus(UART5_INSTANCE, &bytesRemaining);
        if (status != STATUS_SUCCESS) {
            UART_DRV_SendDataBlocking(UART2_INSTANCE, (uint8_t *)"UART5 RX error!\r\n", 17, TIMEOUT);
            break;
        }
        g_bufferldx++;
        g_buffer[g_bufferldx] = 0U;
        UART_DRV_SendDataBlocking(UART2_INSTANCE, g_buffer, g_bufferldx, TIMEOUT);
        g_bufferldx = 0U;
    }
}

/**
 * @brief 从UART5接收一行数据，包含超时和错误处理
 * @param buffer 接收缓冲区
 * @param max_len 最大接收长度
 * @param timeout_ms 超时时间（毫秒）
 * @return 接收到的字符数，-1表示超时或错误
 */
int UART5_ReceiveLine(char *buffer, int max_len, uint32_t timeout_ms)
{
    int idx = 0;
    char ch = 0;
    uint32_t timeout_count = 0;
    const uint32_t timeout_limit = timeout_ms * 1000; // 更精确的超时计算
    
    // 清空缓冲区
    memset(buffer, 0, max_len);
    
    // 打印调试信息
    printf("开始接收UART5数据，超时时间: %d ms\r\n", timeout_ms);
    
    while (idx < max_len - 1) {
        // 尝试接收一个字符
        status_t status = UART_DRV_ReceiveDataPolling(UART5_INSTANCE, (uint8_t*)&ch, 1);
        
        if (status == STATUS_SUCCESS) {
            // 成功接收到字符
            buffer[idx++] = ch;
            timeout_count = 0; // 重置超时计数器
            
            // 打印接收到的字符（十六进制）
            printf("接收到字符: 0x%02X ('%c')\r\n", (unsigned char)ch, (ch >= 32 && ch <= 126) ? ch : '?');
            
            // 转发到UART2用于调试
            UART5_ForwardToUART2(ch);
            
            // 检查是否收到行结束符
            if (ch == '\n' || ch == '\r') {
                printf("收到行结束符，接收完成\r\n");
                break;
            }
        } else {
            // 接收失败，增加超时计数
            timeout_count++;
            if (timeout_count >= timeout_limit) {
                printf("UART5接收超时，已接收 %d 个字符\r\n", idx);
                return -1; // 超时
            }
            
            // 使用更精确的延时
            delay_us(100); // 100微秒延时
        }
    }
    
    buffer[idx] = '\0'; // 确保字符串结束
    printf("UART5接收完成，共接收 %d 个字符: '%s'\r\n", idx, buffer);
    return idx;
}

/**
 * @brief 快速接收UART5数据，减少处理延迟
 * @param buffer 接收缓冲区
 * @param max_len 最大接收长度
 * @param timeout_ms 超时时间（毫秒）
 * @return 接收到的字符数，-1表示超时或错误
 */
int UART5_FastReceiveLine(char *buffer, int max_len, uint32_t timeout_ms)
{
    int idx = 0;
    char ch = 0;
    uint32_t timeout_count = 0;
    const uint32_t timeout_limit = timeout_ms * 1000;
    
    // 清空缓冲区
    memset(buffer, 0, max_len);
    
    printf("开始快速接收UART5数据，超时时间: %d ms\r\n", timeout_ms);
    
    while (idx < max_len - 1) {
        // 尝试接收一个字符
        status_t status = UART_DRV_ReceiveDataPolling(UART5_INSTANCE, (uint8_t*)&ch, 1);
        
        if (status == STATUS_SUCCESS) {
            // 成功接收到字符，立即存储
            buffer[idx++] = ch;
            timeout_count = 0;
            
            // 最小化处理延迟，只做必要的检查
            if (ch == '\n' || ch == '\r') {
                break;
            }
            
            // 非常短的延时，确保能跟上发送速度
            delay_us(10);
        } else {
            // 接收失败，增加超时计数
            timeout_count++;
            if (timeout_count >= timeout_limit) {
                printf("UART5快速接收超时，已接收 %d 个字符\r\n", idx);
                return -1;
            }
            
            // 更短的延时
            delay_us(50);
        }
    }
    
    buffer[idx] = '\0';
    
    // 接收完成后再打印和转发
    printf("UART5快速接收完成，共接收 %d 个字符: '%s'\r\n", idx, buffer);
    for (int i = 0; i < idx; i++) {
        UART5_ForwardToUART2(buffer[i]);
    }
    
    return idx;
}

/**
 * @brief 从UART5接收单个字符，带超时
 * @param ch 接收到的字符
 * @param timeout_ms 超时时间（毫秒）
 * @return 0表示成功，-1表示超时
 */
int UART5_ReceiveChar(char *ch, uint32_t timeout_ms)
{
    uint32_t timeout_count = 0;
    const uint32_t timeout_limit = timeout_ms * 1000;
    
    while (timeout_count < timeout_limit) {
        status_t status = UART_DRV_ReceiveDataPolling(UART5_INSTANCE, (uint8_t*)ch, 1);
        
        if (status == STATUS_SUCCESS) {
            return 0; // 成功
        }
        
        timeout_count++;
        delay_us(100);
    }
    
    return -1; // 超时
}

/**
 * @brief 专门用于处理ERR格式数据的快速接收函数
 * @param buffer 接收缓冲区
 * @param max_len 最大接收长度
 * @param timeout_ms 超时时间（毫秒）
 * @return 接收到的字符数，-1表示超时或错误
 */
int UART5_ReceiveERRData(char *buffer, int max_len, uint32_t timeout_ms)
{
    int idx = 0;
    char ch = 0;
    uint32_t timeout_count = 0;
    const uint32_t timeout_limit = timeout_ms * 1000;
    bool found_start = false;
    
    // 清空缓冲区
    memset(buffer, 0, max_len);
    
    printf("开始接收ERR格式数据，超时时间: %d ms\r\n", timeout_ms);
    
    while (idx < max_len - 1) {
        // 尝试接收一个字符
        status_t status = UART_DRV_ReceiveDataPolling(UART5_INSTANCE, (uint8_t*)&ch, 1);
        
        if (status == STATUS_SUCCESS) {
            // 成功接收到字符
            buffer[idx++] = ch;
            timeout_count = 0; // 重置超时计数器
            
            // 检查是否找到起始符
            if (ch == '$' && !found_start) {
                found_start = true;
                printf("找到起始符 $\r\n");
            }
            
            // 检查是否收到行结束符
            if (ch == '\n' || ch == '\r') {
                printf("收到行结束符，接收完成\r\n");
                break;
            }
            
            // 最小化处理延迟，只做必要的检查
            delay_us(5); // 5微秒延时
        } else {
            // 接收失败，增加超时计数
            timeout_count++;
            if (timeout_count >= timeout_limit) {
                printf("UART5接收超时，已接收 %d 个字符\r\n", idx);
                return -1; // 超时
            }
            
            // 更短的延时
            delay_us(20);
        }
    }
    
    buffer[idx] = '\0'; // 确保字符串结束
    
    // 接收完成后再打印和转发
    printf("UART5 ERR数据接收完成，共接收 %d 个字符: '%s'\r\n", idx, buffer);
    for (int i = 0; i < idx; i++) {
        UART5_ForwardToUART2(buffer[i]);
    }
    
    return idx;
}

/**
 * @brief 解析ERR格式数据
 * @param buffer 接收到的数据缓冲区
 * @param id 输出：二维码ID
 * @param err_x 输出：X方向误差
 * @param err_y 输出：Y方向误差
 * @param err_theta 输出：角度误差
 * @return 解析成功返回true，失败返回false
 */
bool UART5_ParseERRData(const char* buffer, int* id, float* err_x, float* err_y, float* err_theta)
{
    if (!buffer || !id || !err_x || !err_y || !err_theta) {
        return false;
    }
    
    // 检查是否是ERR格式
    if (strncmp(buffer, "$ERR,", 5) != 0) {
        printf("数据格式不是ERR格式\r\n");
        return false;
    }
    
    // 解析数据：$ERR,1,41.5,-12.5,89.0
    char* token = strtok((char*)buffer, ",");
    if (!token) return false;
    
    // 跳过$ERR
    token = strtok(NULL, ",");
    if (!token) return false;
    *id = atoi(token);
    
    // 解析err_x
    token = strtok(NULL, ",");
    if (!token) return false;
    *err_x = atof(token);
    
    // 解析err_y
    token = strtok(NULL, ",");
    if (!token) return false;
    *err_y = atof(token);
    
    // 解析err_theta
    token = strtok(NULL, ",");
    if (!token) return false;
    *err_theta = atof(token);
    
    printf("ERR数据解析成功: ID=%d, err_x=%.1f, err_y=%.1f, err_theta=%.1f\r\n", 
           *id, *err_x, *err_y, *err_theta);
    
    return true;
}

/**
 * @brief 简化的ERR数据接收和处理函数
 * @param id 输出：二维码ID
 * @param err_x 输出：X方向误差
 * @param err_y 输出：Y方向误差
 * @param err_theta 输出：角度误差
 * @param timeout_ms 超时时间（毫秒）
 * @return 接收成功返回true，失败返回false
 */
bool UART5_ReceiveAndParseERR(int* id, float* err_x, float* err_y, float* err_theta, uint32_t timeout_ms)
{
    char buffer[128];
    int received = UART5_ReceiveERRData(buffer, 128, timeout_ms);
    
    if (received > 0) {
        return UART5_ParseERRData(buffer, id, err_x, err_y, err_theta);
    }
    
    return false;
} 

// ================== 补充未定义函数实现 ==================
void delay_us(unsigned int us) {
    volatile unsigned int count;
    while(us--) {
        count = 50; // 具体数值根据主频调整
        while(count--);
    }
}

void UART5_ForwardToUART2(uint8_t ch) {
    // 如需转发到UART2，可用如下代码：
    UART_DRV_SendDataBlocking(UART2_INSTANCE, &ch, 1, 100);
    // 目前为空实现，仅防止链接错误
} 